package  
{
	import com.buraks.utils.fastmem;
	import flash.geom.Vector3D;
	import flash.utils.ByteArray;
	import starling.core.Starling;
	import starling.display.Quad;
	import starling.display.Sprite;
	
	/**
	 * ...
	 * @author Guillaume Sylvain
	 */
	public class Boid
	{
		public static const DATA_SIZE:int = 4 * 4;
		private var mStageWidth:int = 1280;
		private var mStageHeight:int = 720;
		public var mFriend:Boid = null;
		public var mEnemy:Boid = null;
		public var mPos:Vector3D 	= new Vector3D();
		private var mBind:Vector3D 	= new Vector3D();
		private var mVec:Vector3D 	= new Vector3D();
		private var mSpeed:Number = 10;
		private var mPercent:Number = 0;
		private var mQuad:Quad = null;
		private var mSquareMoveToBindDist:Number = 0;
		
		public function Boid(aContainer:Sprite) 
		{
			mStageWidth = Starling.current.stage.stageWidth;
			mStageHeight = Starling.current.stage.stageHeight;
			mSquareMoveToBindDist = (mStageHeight / 2) * (mStageHeight / 2)
			mQuad = new Quad(1, 1, 0xF6F87B);
			aContainer.addChild(mQuad);
			mSpeed += Math.random() - 0.5;
		}
		
		public function Serialize(aByteArray:ByteArray, aPos:int):void
		{
			fastmem.fastSetFloat(mPos.x, aPos); aPos += 4;
			fastmem.fastSetFloat(mPos.y, aPos); aPos += 4;
			fastmem.fastSetFloat(mQuad.scaleX, aPos); aPos += 4;
			fastmem.fastSetFloat(mQuad.alpha, aPos);
		}
		
		public function Deserialize(aByteArray:ByteArray, aPos:int):void
		{
			mQuad.x = fastmem.fastGetFloat(aPos); aPos += 4;
			mQuad.y = fastmem.fastGetFloat(aPos); aPos += 4;
			mQuad.scaleX = mQuad.scaleY = fastmem.fastGetFloat(aPos); aPos += 4;
			mQuad.alpha = fastmem.fastGetFloat(aPos);
		}
		
		public function UpdatePos():void
		{
			Move(mFriend.mPos, 2 * mSpeed);
			Move(mEnemy.mPos, -1 * mSpeed);
			MoveToBind(mBind, 0.5 * mSpeed);
			
			mPercent = (mStageHeight - mPos.z) / mStageHeight;
			if (mPercent < 0) mPercent = 0;
			if (mPercent > 100) mPercent = 100;
			
			mQuad.scaleX = mQuad.scaleY = mPercent * (6 - 1) + 1;
			mQuad.alpha = (1 - mPercent) * (1 - 0.4) + 0.4;
		}
		
		private function MoveToBind(aTarget:Vector3D, aSpeed:Number):void
		{
			mVec.x = aTarget.x - mPos.x;
			mVec.y = aTarget.y - mPos.y;
			mVec.z = aTarget.z - mPos.z
			
			aSpeed *= mVec.lengthSquared / mSquareMoveToBindDist;
			
			mVec.normalize();
			mVec.scaleBy(aSpeed);
			
			mPos.x += mVec.x;
			mPos.y += mVec.y;
			mPos.z += mVec.z;
		}
		
		private var mSquareMoveDist:Number = 30 * 30;
		private var mMoveLength:Number = 0;
		private function Move(aTarget:Vector3D, aSpeed:Number):void 
		{
			mVec.x = aTarget.x - mPos.x;
			mVec.y = aTarget.y - mPos.y;
			mVec.z = aTarget.z - mPos.z;
			
			mMoveLength = (mVec.x * mVec.x) + (mVec.y * mVec.y) + (mVec.z * mVec.z);
			if (mMoveLength < mSquareMoveDist)
			{
				aSpeed *= (mMoveLength / mSquareMoveDist) * 0.5;
			}
			
			mVec.normalize();
			mVec.scaleBy(aSpeed);
			
			mPos.x += mVec.x;
			mPos.y += mVec.y;
			mPos.z += mVec.z;
		}
		
		public function SetBindPos(aX:Number, aY:Number, aZ:Number = 0):void
		{
			mBind.x = aX;
			mBind.y = aY;
			mBind.z = aZ;
		}
	}
}